package org.demo2;

import com.github.javaparser.JavaParser;
import com.github.javaparser.ParseResult;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.expr.StringLiteralExpr;
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 查找字符串中的
 */
public class SqlKeywordFinder {

    // 定义常见的 SQL 关键字
    private static final List<String> SQL_KEYWORDS = Arrays.asList(
            "SELECT", "INSERT", "UPDATE", "DELETE", "FROM", "WHERE", "JOIN", "ON", "AND", "OR", "GROUP BY", "ORDER BY"
    );

    // 正则表达式用于匹配 SQL 关键字
    private static final Pattern SQL_KEYWORD_PATTERN = Pattern.compile(
            "\\b(" + String.join("|", SQL_KEYWORDS) + ")\\b", Pattern.CASE_INSENSITIVE
    );

    public static void main(String[] args) {
        String directoryPath = "E:\\yy_work\\project\\SEM_EPM_P";
        File directory = new File(directoryPath);
        if (!directory.isDirectory()) {
            System.out.println("The provided path is not a directory.");
            return;
        }

        try {
            // 获取目录下的所有 .java 文件
            List<File> javaFiles = Files.walk(Paths.get(directoryPath))
                    .filter(Files::isRegularFile)
                    .filter(path -> path.toString().endsWith(".java"))
                    .map(Path::toFile)
                    .collect(Collectors.toList());

            // 遍历每个 Java 文件
            for (File file : javaFiles) {
                findSqlKeywordsInFile(file);
            }
        } catch (IOException e) {
            System.err.println("Error reading files: " + e.getMessage());
        }
    }

    private static void findSqlKeywordsInFile(File file) {
        try {
            FileInputStream in = new FileInputStream(file);
            // 解析 Java 文件
            JavaParser javaParser = new JavaParser();
            ParseResult<CompilationUnit> parseResult = javaParser.parse(in);
            if (parseResult.isSuccessful()) {
                CompilationUnit cu = parseResult.getResult().get();

                // 创建一个 Visitor 来查找 SQL 关键字
                cu.accept(new VoidVisitorAdapter<Void>() {
                    @Override
                    public void visit(ClassOrInterfaceDeclaration n, Void arg) {
                        super.visit(n, arg);
                        // 记录当前类名
                        String className = n.getNameAsString();
                        // 查找类中的所有字符串字面量
                        n.findAll(StringLiteralExpr.class).forEach(stringLiteral -> {
                            checkForSqlKeywords(className, stringLiteral, file);
                        });
                    }
                }, null);
            } else {
                System.err.println("Failed to parse file: " + file.getAbsolutePath());
            }
        } catch (IOException e) {
            System.err.println("Error reading file: " + file.getAbsolutePath() + " - " + e.getMessage());
        }
    }

    private static void checkForSqlKeywords(String className, StringLiteralExpr stringLiteral, File file) {
        String sqlString = stringLiteral.getValue();
        Matcher matcher = SQL_KEYWORD_PATTERN.matcher(sqlString);

        while (matcher.find()) {
            // 找到 SQL 关键字
            String keyword = matcher.group().toUpperCase();
            int lineNumber = getLineNumber(file, stringLiteral);

            // 输出结果
            System.out.printf("Str '%s' Found SQL keyword '%s' in class '%s' at line %d in file: %s%n",
                    sqlString, keyword, className, lineNumber, file.getAbsolutePath());
        }
    }

    private static int getLineNumber(File file, StringLiteralExpr stringLiteral) {
        try {
            // 读取文件内容并找到字符串字面量所在的行号
            List<String> lines = Files.readAllLines(file.toPath());
            return stringLiteral.getBegin().orElseThrow(() -> new NoSuchElementException("No line information")).line;
        } catch (IOException e) {
            System.err.println("Error reading file: " + file.getAbsolutePath() + " - " + e.getMessage());
            return -1;
        }
    }

}